package com.example.nativecamera;

import android.Manifest;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.pm.PackageManager;
import android.media.MediaRecorder;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.provider.MediaStore;
import android.util.Log;
import android.os.Trace;
import android.graphics.PixelFormat;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Date;
import java.util.Locale;

/**
 * 主活动类，负责相机预览和拍照功能
 */
public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback {
    
    private static final String TAG = "NativeCameraMain";
    private static final String FILENAME_FORMAT = "yyyy-MM-dd-HH-mm-ss-SSS";
    
    // 基础权限
    private static final String[] BASE_PERMISSIONS = {
        Manifest.permission.CAMERA
    };
    
    // 传统存储权限（Android 9及以下）
    private static final String[] LEGACY_STORAGE_PERMISSIONS = {
        Manifest.permission.READ_EXTERNAL_STORAGE,
        Manifest.permission.WRITE_EXTERNAL_STORAGE
    };
    
    // 媒体权限（Android 10+）
    private static final String[] MEDIA_PERMISSIONS = {
        Manifest.permission.READ_MEDIA_IMAGES
    };
    
    // UI 控件
    private SurfaceView surfaceView;
    private Button captureButton;
    private Button switchCameraButton;
    private TextView statusText;
    
    // 状态变量
    private boolean isCameraInitialized = false;
    private boolean isPreviewActive = false;
    private String currentCameraId = "0"; // 默认后置相机
    
    // 权限请求启动器
    private final ActivityResultLauncher<String[]> activityResultLauncher =
            registerForActivityResult(
                    new ActivityResultContracts.RequestMultiplePermissions(),
                    permissions -> {
                        boolean allGranted = true;
                        for (Boolean granted : permissions.values()) {
                            if (!granted) {
                                allGranted = false;
                                break;
                            }
                        }
                        
                        if (allGranted) {
                            Log.i(TAG, "所有权限已授予");
                            initializeCamera();
                        } else {
                            Log.e(TAG, "权限被拒绝");
                            showToast("需要相机和存储权限才能使用应用");
                            finish();
                        }
                    });

    // 加载原生库
    static {
        System.loadLibrary("nativecamera");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Trace.beginSection("MainActivity.onCreate");
        
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        // 初始化UI组件
        initializeViews();
        
        // 设置按钮监听器
        setupButtonListeners();
        
        // 检查并请求权限
        if (allPermissionsGranted()) {
            initializeCamera();
        } else {
            requestPermissions();
        }
        
        Trace.endSection();
    }

    /**
     * 初始化UI组件
     */
    private void initializeViews() {
        Trace.beginSection("MainActivity.initializeViews");
        
        surfaceView = findViewById(R.id.viewFinder);
        captureButton = findViewById(R.id.image_capture_button);
        switchCameraButton = findViewById(R.id.camera_switch_button);
        statusText = findViewById(R.id.status_text);
        
        // 设置SurfaceView回调
        SurfaceHolder holder = surfaceView.getHolder();
        holder.addCallback(this);
        
        // 设置Surface格式
        holder.setFormat(PixelFormat.RGBA_8888);
        
        Trace.endSection();
    }

    /**
     * 设置按钮监听器
     */
    private void setupButtonListeners() {
        // 拍照按钮
        captureButton.setOnClickListener(v -> {
            if (isCameraInitialized && isPreviewActive) {
                takePhoto();
            } else {
                showToast("相机未准备好");
            }
        });
        
        // 切换相机按钮
        switchCameraButton.setOnClickListener(v -> {
            if (isCameraInitialized) {
                switchCamera();
            }
        });
        
        Log.i(TAG, "按钮监听器设置完成");
    }

    /**
     * 初始化相机
     */
    private void initializeCamera() {
        Trace.beginSection("MainActivity.initializeCamera");
        
        boolean success = nativeInitCamera();
        
        if (success) {
            isCameraInitialized = true;
            
            // 获取可用相机列表
            String[] cameras = nativeGetAvailableCameras();
            if (cameras != null && cameras.length > 0) {
                for (String camera : cameras) {
                    Log.i(TAG, "相机设备: " + camera);
                }
                
                // 打开默认相机
                openCamera(currentCameraId);
            } else {
                showToast("未发现相机设备");
            }
        } else {
            showToast("初始化相机失败");
        }
        
        Trace.endSection();
    }

    /**
     * 打开指定相机
     */
    private void openCamera(String cameraId) {
        Trace.beginSection("MainActivity.openCamera");
        
        boolean success = nativeOpenCamera(cameraId);
        
        if (success) {
            currentCameraId = cameraId;
            updateStatusText("相机已打开: " + cameraId);
            
            // 如果Surface已准备好，开始预览
            if (surfaceView.getHolder().getSurface().isValid()) {
                startPreview();
            }
        } else {
            showToast("打开相机失败");
        }
        
        Trace.endSection();
    }

    /**
     * 开始预览
     */
    private void startPreview() {
        Trace.beginSection("MainActivity.startPreview");
        
        Surface surface = surfaceView.getHolder().getSurface();
        
        // 检查Surface是否有效
        if (surface == null || !surface.isValid()) {
            showToast("预览Surface无效");
            Trace.endSection();
            return;
        }
        
        Log.d(TAG, "StartPreview: Surface信息 - isValid=" + surface.isValid());
        
        boolean success = nativeStartPreview(surface);
        
        if (success) {
            isPreviewActive = true;
            updateStatusText("预览已开始");
        } else {
            showToast("开始预览失败");
        }
        
        Trace.endSection();
    }

    /**
     * 停止预览
     */
    private void stopPreview() {
        Log.i(TAG, "停止相机预览");
        
        if (isPreviewActive) {
            nativeStopPreview();
            isPreviewActive = false;
            updateStatusText("预览已停止");
        }
    }

    /**
     * 拍照功能
     */
    private void takePhoto() {
        Trace.beginSection("MainActivity.takePhoto");
        
        if (!isCameraInitialized) {
            showToast("相机未初始化");
            Trace.endSection();
            return;
        }

        if (!nativeIsCameraOpen()) {
            showToast("相机未打开");
            Trace.endSection();
            return;
        }

        try {
            // 生成文件名
            Trace.beginSection("takePhoto.generateFilename");
            String timeStamp = new SimpleDateFormat(FILENAME_FORMAT, Locale.getDefault()).format(new Date());
            String filename = "IMG_" + timeStamp + ".jpg";
            String filepath = getExternalFilesDir(Environment.DIRECTORY_PICTURES) + "/" + filename;
            Trace.endSection();
            
            // 调用native方法拍照，传递完整路径
            Trace.beginSection("takePhoto.nativeTakePicture");
            boolean success = nativeTakePicture(filepath);
            Trace.endSection();
            
            if (success) {
                showToast("拍照成功");
                
                // 等待文件生成
                new Thread(() -> {
                    Trace.beginSection("takePhoto.waitForFile");
                    boolean fileReady = waitForFileGeneration(filepath, 5000);
                    Trace.endSection();
                    
                    if (fileReady) {
                        runOnUiThread(() -> {
                            try {
                                // 保存到媒体库
                                Trace.beginSection("takePhoto.saveToMediaStore");
                                ContentResolver resolver = getContentResolver();
                                ContentValues values = new ContentValues();
                                values.put(MediaStore.Images.Media.DISPLAY_NAME, filename);
                                values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
                                values.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES);
                                
                                Uri uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
                                if (uri != null) {
                                    copyFileToMediaStore(filepath, uri, filename);
                                    showToast("照片已保存到相册");
                                } else {
                                    showToast("保存到相册失败");
                                }
                                Trace.endSection();
                            } catch (Exception e) {
                                Trace.endSection();
                                showToast("保存照片时出错: " + e.getMessage());
                            }
                        });
                    } else {
                        runOnUiThread(() -> showToast("照片文件生成超时"));
                    }
                }).start();
            } else {
                showToast("拍照失败");
            }
        } catch (Exception e) {
            showToast("拍照时出错: " + e.getMessage());
        }
        
        Trace.endSection();
    }

    /**
     * 等待文件生成
     * @param filepath 文件路径
     * @param timeoutMs 超时时间（毫秒）
     * @return true 如果文件已生成，false 如果超时
     */
    private boolean waitForFileGeneration(String filepath, long timeoutMs) {
        long startTime = System.currentTimeMillis();
        File file = new File(filepath);
        
        while (System.currentTimeMillis() - startTime < timeoutMs) {
            if (file.exists() && file.length() > 0) {
                return true;
            }
            
            try {
                Thread.sleep(10); // 等待100ms后重试
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                break;
            }
        }
        
        return false;
    }
    
    /**
     * 将文件复制到MediaStore，带有性能追踪
     * @param sourcePath 源文件路径
     * @param targetUri 目标URI
     * @param filename 文件名
     */
    private void copyFileToMediaStore(String sourcePath, Uri targetUri, String filename) {
        Trace.beginSection("copyFileToMediaStore");
        java.io.FileInputStream fis = null;
        java.io.OutputStream os = null;
        
        try {
            // 检查源文件是否存在
            Trace.beginSection("copyFile.checkSourceFile");
            File sourceFile = new File(sourcePath);
            if (!sourceFile.exists()) {
                Trace.endSection();
                showToast("拍照失败：文件未生成");
                return;
            }
            
            if (sourceFile.length() == 0) {
                Trace.endSection();
                showToast("拍照失败：文件为空");
                return;
            }
            Trace.endSection();
            
            Trace.beginSection("copyFile.openStreams");
            fis = new java.io.FileInputStream(sourceFile);
            os = getContentResolver().openOutputStream(targetUri);
            Trace.endSection();
            
            if (os != null) {
                Trace.beginSection("copyFile.copyData");
                byte[] buffer = new byte[8192];
                int bytesRead;
                long totalBytes = 0;
                
                while ((bytesRead = fis.read(buffer)) != -1) {
                    os.write(buffer, 0, bytesRead);
                    totalBytes += bytesRead;
                }
                Trace.endSection();
                
                // 删除临时文件
                Trace.beginSection("copyFile.deleteTemp");
                sourceFile.delete();
                Trace.endSection();
                
                runOnUiThread(() -> {
                    showToast("照片已保存: " + filename);
                });
            } else {
                showToast("保存照片失败：无法写入相册");
            }
        } catch (Exception e) {
            Log.e(TAG, "复制到MediaStore失败", e);
            showToast("保存照片失败: " + e.getMessage());
        } finally {
            // 确保流被正确关闭
            try {
                if (fis != null) fis.close();
                if (os != null) os.close();
            } catch (Exception e) {
                Log.e(TAG, "关闭流时出错", e);
            }
            Trace.endSection();
        }
    }

    /**
     * 切换相机
     */
    private void switchCamera() {
        Trace.beginSection("MainActivity.switchCamera");
        
        try {
            // 停止预览
            stopPreview();
            
            // 关闭当前相机
            nativeCloseCamera();
            
            // 切换相机ID
            currentCameraId = currentCameraId.equals("0") ? "1" : "0";
            
            // 打开新相机
            openCamera(currentCameraId);
            
            // 如果surface已准备好，启动预览
            if (surfaceView.getHolder().getSurface().isValid()) {
                startPreview();
            }
            
            showToast("已切换到" + (currentCameraId.equals("0") ? "后置" : "前置") + "相机");
            
        } catch (Exception e) {
            showToast("切换相机失败: " + e.getMessage());
        }
        
        Trace.endSection();
    }

    /**
     * 更新状态文本
     */
    private void updateStatusText(String text) {
        runOnUiThread(() -> {
            if (statusText != null) {
                statusText.setText(text);
            }
        });
    }

    /**
     * 获取当前Android版本需要的权限
     */
    private String[] getRequiredPermissions() {
        List<String> permissions = new ArrayList<>();
        
        // 添加基础权限
        permissions.addAll(Arrays.asList(BASE_PERMISSIONS));
        
        // 根据Android版本添加存储权限
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            // Android 13+ 使用细粒度媒体权限
            permissions.addAll(Arrays.asList(MEDIA_PERMISSIONS));
        } else {
            // Android 12及以下使用传统存储权限
            permissions.addAll(Arrays.asList(LEGACY_STORAGE_PERMISSIONS));
        }
        
        return permissions.toArray(new String[0]);
    }

    /**
     * 检查是否所有权限都已授予
     */
    private boolean allPermissionsGranted() {
        String[] requiredPermissions = getRequiredPermissions();
        for (String permission : requiredPermissions) {
            if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
        }
        return true;
    }

    /**
     * 请求权限
     */
    private void requestPermissions() {
        activityResultLauncher.launch(getRequiredPermissions());
    }

    /**
     * 显示Toast消息
     */
    /**
     * 显示Toast消息，带有性能追踪
     * @param message 要显示的消息内容
     */
    private void showToast(String message) {
        Trace.beginSection("MainActivity.showToast");
        try {
            runOnUiThread(() -> {
                Trace.beginSection("Toast.makeText.show");
                try {
                    Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
                } finally {
                    Trace.endSection();
                }
            });
        } finally {
            Trace.endSection();
        }
    }

    // SurfaceHolder.Callback 实现
    @Override
    public void surfaceCreated(@NonNull SurfaceHolder holder) {
        Log.d(TAG, "SurfaceCreated: Surface 创建完成，等待surfaceChanged");
        // Surface创建后，等待surfaceChanged确定尺寸后再启动预览
        // 这样可以避免在Surface尺寸未确定时启动预览
    }

    @Override
    public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
        Log.d(TAG, "SurfaceChanged: Surface 改变: " + width + "x" + height + ", format: " + format + 
              ", isPreviewActive=" + isPreviewActive + 
              ", isCameraInitialized=" + isCameraInitialized + 
              ", isCameraOpen=" + nativeIsCameraOpen());
        
        // 只有在预览未激活且相机已初始化时才启动预览
        // 避免在Surface初始化过程中重复启动预览
        if (!isPreviewActive && isCameraInitialized && nativeIsCameraOpen()) {
            Log.d(TAG, "SurfaceChanged: Surface尺寸确定后启动预览");
            startPreview();
        } else {
            Log.d(TAG, "SurfaceChanged: 不满足预览条件，跳过预览启动");
        }
    }

    @Override
    public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
        Log.i(TAG, "Surface 销毁");
        stopPreview();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i(TAG, "MainActivity 销毁");
        
        // 停止预览
        stopPreview();
        
        // 清理原生资源
        nativeCleanup();
    }

    // Native方法声明
    public native boolean nativeInitCamera();

    /**
     * 获取可用相机列表
     */
    public native String[] nativeGetAvailableCameras();

    /**
     * 打开指定相机
     */
    public native boolean nativeOpenCamera(String cameraId);

    /**
     * 关闭相机
     */
    public native void nativeCloseCamera();

    /**
     * 开始预览
     */
    public native boolean nativeStartPreview(Surface surface);

    /**
     * 停止预览
     */
    public native void nativeStopPreview();

    /**
     * 拍照
     */
    public native boolean nativeTakePicture(String filename);

    /**
     * 检查相机是否打开
     */
    public native boolean nativeIsCameraOpen();

    /**
     * 清理资源
     */
    public native void nativeCleanup();


}